﻿using System.Collections;
using System.Collections.Generic;
using System.IO;
using UnityEngine;

public class GuideMgr: IZUpdate, IBaseData
{
    private List<uint> guidePoint = new List<uint>();
    private List<uint> guideGroup = new List<uint>();

    private List<Table_GuideVOItem> filterList = new List<Table_GuideVOItem>();
    private Dictionary<int, Table_GuideVOItem> guideList;
    
    private int noPanelId = -1;
    private bool isOpenTrigger = true;
    private bool newGuideFlag = false;

    public bool IsDelaying { get; set; }
    public bool IsGuideInit { get; set; }
    public Table_GuideVOItem GuideVO { get; set; }
    
    public bool IsRun
    {
        get { return IsDelaying || GuideVO != null; }
    }
    
    public bool IsInit
    {
        get { return IsGuideInit || IsNewGuide(); }
    }
    
    public GuideMgr()
    {
        guideList = new Dictionary<int, Table_GuideVOItem>(); Init();
        ZEventCenter.AddEventListener(ConstData.OPENED_PANEL, OnOpenUI);
        ZEventCenter.AddEventListener(ConstData.CLOSE_PANEL, OnCloseUI);
        ZEventCenter.AddEventListener(ConstData.GUIDE_ENTER_FUBEN, OnEnterFuben);
    }

    public void Init()
    {
        for (int i = 0; i < TableDataMgr.GuideVOMgr.mDataCount; i++)
        {
            var item = TableDataMgr.GuideVOMgr.GetItemByIdx(i);
            if (item == null) { continue; }

            guideList.Add(item.Id, item);
            uint groupId = (uint)item.GroupId;
            if (!guideGroup.Contains(groupId))
            {
                guideGroup.Add(groupId);
            }
            guidePoint.Add((uint)item.Id);
        }
    }

    public void ZUpdate()
    {
        
    }
    
    private void SendJingfenLog(int panelId)
    {

    }

    private bool IsNewGuide()
    {
        return false;
    }

    private void OnOpenUI(ZEvent ev)
    {
        var data = ev.eventObj as Table_UIPathItem;
        SendJingfenLog(data.Id);
        FilterGuideByUIID(data.Id, true);
    }

    private void OnCloseUI(ZEvent ev)
    {
        var data = ev.eventObj as Table_UIPathItem;
        FilterGuideByUIID(data.Id, false);
    }

    private void FilterGuideByUIID(int uId, bool open)
    {
        if (IsRun || !DBSystemMgr.GetSingleton().CfgInited) { return; }

        //中断指引有升级弹出，先弹出升级
        if (uId == (int)PanelID.MainMenuPanel)
        {
            noPanelId = uId;
            isOpenTrigger = open;
            return;
        }
        CheckPanelIDGuide(uId, open);
    }
    
    public void CheckPanelIDGuide(int panelId, bool open)
    {
        var vo = GetDbByUI(panelId, open);
        if (vo != null)
        {
            CheckGuide(vo);
        }
        else if (CanCheckLvUp(panelId))
        {
            OnCheckGuideByLvlUp();
        }
    }
    
    private void CheckGuide(Table_GuideVOItem vo)
    {
        if (!IsInit) { return; }
        if (GuideVO != null)
        {
            if (GuideVO.Id == vo.Id)
            {
                //和当前指引是同一条
                return;
            }
            if (GuideVO.Priority > vo.Priority)
            {
                //优先级低于当前指引
                return;
            }
        }
        if (vo.DelayTime > 0)
        {
            //不强制指引的时候，不要锁屏
            if (vo.FunType != (int)GuideFunType.freeClick)
            {
                UIInputMgr.GetSingleton().LockInput(LockType.GuideDelay);
            }
            else
            {
                UIInputMgr.GetSingleton().UnLockInput(LockType.GuideDelay);
            }
            IsDelaying = true;
            ZMgr.TimerMgr.SetTimeOut(ExecGuide, vo.DelayTime, vo);
            GuideVO = vo;
        }
        else
        {
            ExecGuide(vo);
        }
    }

    private void OnCheckGuideByLvlUp()
    {
        if (IsRun) { return; }  
        // 不在副本中才检测等级相关的

        int lvId = PlayerData.GetSingleton().roleAttr.level;
        for (int i = 1; i <= lvId; i++)
        {
            var vo = GetDbByLv(i);
            if (vo != null)
            {
                CheckGuide(vo);
            }
        }
    }
    
    private void ExecGuide(Table_GuideVOItem vo)
    {
        IsDelaying = false;
        GuideVO = null;
        if (IsInit) { return; }

        GuideVO = vo;
        if (GuideVO.IsPause)
        {
            //暂停游戏
        }
        if (GuideVO.DelayTime > 0)
        {
            UIInputMgr.GetSingleton().UnLockInput(LockType.GuideDelay);
        }
        //打开新手指引UI
    }

    public void StopGuide()
    {
        ZEventCenter.DispatchEvent(new ZEvent(ConstData.GUIDE_BREAK));

        IsDelaying = false;
        IsGuideInit = false;
        Time.timeScale = 1;
    }

    public void Finish()
    {
        if (GuideVO.IsPause)
        {
            //继续游戏
        }
        SetGuide(GuideVO.Id, true);
        //if (!GuideVO.IsNewGuideUse)
        //{
            
        //}
        //else //是新手关要另外存储
        //{
            
        //}

        if (GuideVO == null) { return; }
        
        if (GuideVO.Finish)
        {
            if (SetGuide(GuideVO.GroupId, true, 1))
            {
                //if (!GuideVO.IsNewGuideUse) //不是新手关才发送新手引导信息
                //{
                    
                //}
                ZEventCenter.DispatchEvent(new ZEvent(ConstData.GUIDE_FINISH, GuideVO.Id));
                OnCheckGuideByLvlUp();  //当指引组完成后，检测是否有根据等级提升的指引
            }
        }
        var vo = GetDbByID(GuideVO.Id);
        
        GuideVO = null;
        if (vo != null)
        {
            //触发后置指引
            CheckGuide(vo);
        }
    }
    
    public bool CanCheckLvUp(int id)
    {
        switch ((PanelID)id)
        {
            case PanelID.LoginPanel:
            case PanelID.LoadingPanel:
                return false;
        }
        return true;
    }

    public bool IsInGuiding(int guideId)
    {
        if (GuideVO == null || GuideVO.Id != guideId)
        {
            return false;
        }
        return true;
    }
    
    public bool IsGuide(int id, int idType = 0)
    {
        if (!IsInit || id >= GlobalNum.MAX_GUIDEID)
        {
            return false;
        }
        int idx = id / 32; int k = id % 32;
        var list = idType == 0 ? guidePoint : guideGroup;
        return (list[idx] >> k & 1u) == 1;
    }
    
    public bool IsOpenFun(int id)
    {
        if (IsInit && guideList.ContainsKey(id))
        {
            return IsGuide(guideList[id].GroupId, 1);
        }
        return false;
    }
    
    public bool SetGuide(int id, bool choose, int idType = 0)
    {
        if (!IsInit || id >= GlobalNum.MAX_GUIDEID)
        {
            return false;
        }
        int idx = id / 32; int k = id % 32;
        var list = idType == 0 ? guidePoint : guideGroup;
        
        if (choose)
        {
            list[idx] = list[idx] | (1u << k);
        }
        else
        {
            list[idx] = list[idx] & (~(1u << k));
        }
        return true;
    }
    
    public void SetGroup(int id, bool choose)
    {
        SetGuide(id, choose, 1);
        for (int i = 0; i < guideList.Count; i++)
        {
            if (guideList[i].GroupId == id)
            {
                SetGuide(guideList[i].Id, choose, 0);
            }
        }
    }
    
    public bool CheckMust(Table_GuideVOItem vo)
    {
        if (vo.PreId > 0 && !IsGuide(vo.PreId))
        {
            return false;
        }
        if (vo.PreGroupId > 0 && !IsGuide(vo.PreGroupId, 1))
        {
            return false;
        }
        if (vo.CheckGroupId && IsGuide(vo.GroupId, 1))
        {
            return false;
        }
        
        if (!vo.JudgeTag) { return true; }
        for (int i = 0; i < vo.GetOpenUICount(); i++)
        {
            int id = vo.GetOpenUIbyIndex(i);
            if (id > 0 && !ZMgr.UIMgr.IsOpenListHasUI(id))
            {
                return false;
            }
        }
        return true;
    }

    public Table_GuideVOItem GetGuideVO(int guideId)
    {
        if (!guideList.ContainsKey(guideId))
        {
            return null;
        }
        return guideList[guideId];
    }

    public Table_GuideVOItem GetDbByID(int guideId)
    {
        var guidevo = GetGuideVO(guideId);
        if (!CheckMust(guidevo)) { guidevo = null; }
        return guidevo;
    }

    public Table_GuideVOItem GetDbByUI(int uid, bool open)
    {
        if (!IsInit) { return null; }
        if (open)
        {
            for (int i = 0; i < guideList.Count; i++)
            {
                if (guideList[i].OpenUId == uid)
                {
                    filterList.Add(guideList[i]);
                }
            }
        }
        else
        {
            for (int i = 0; i < guideList.Count; i++)
            {
                if (guideList[i].CloseUId == uid)
                {
                    filterList.Add(guideList[i]);
                }
            }
        }
        return GetGuideVOItem();
    }

    public Table_GuideVOItem GetDbByLv(int level)
    {
        if (!IsInit) { return null; }
        for (int i = 0; i < guideList.Count; i++)
        {
            if (guideList[i].UserLv == level)
            {
                filterList.Add(guideList[i]);
            }
        }
        return GetGuideVOItem();
    }

    public Table_GuideVOItem GetDbByEnterFB(int fbId)
    {
        if (!IsInit) { return null; }
        for (int i = 0; i < guideList.Count; i++)
        {
            if (guideList[i].EnterFBId == fbId)
            {
                filterList.Add(guideList[i]);
            }
        }
        return GetGuideVOItem();
    }

    public Table_GuideVOItem GetDbByWinFB(int fbId)
    {
        if (!IsInit) { return null; }
        for (int i = 0; i < guideList.Count; i++)
        {
            if (guideList[i].WinFBId == fbId)
            {
                filterList.Add(guideList[i]);
            }
        }
        return GetGuideVOItem();
    }

    public Table_GuideVOItem GetGuideVOItem()
    {
        Table_GuideVOItem guidevo = null;
        if (filterList.Count <= 0) { return guidevo; }

        for (int i = 0; i < filterList.Count; i++)
        {
            var vo = filterList[i];
            if (CheckMust(vo))
            {
                if (guidevo == null || guidevo.Priority < vo.Priority)
                {
                    guidevo = vo;
                }
            }
        }
        filterList.Clear(); return guidevo;
    }

    /// <summary>
    /// 是否已经完成新手关卡
    /// </summary>
    public bool IsFinishGuideFuben()
    {
        //如果存在文件，说明已经完成
        ArrayList strList = GameTool.GetFile("guide");
        if (strList != null && strList.Count >= 3) { return true; }
        return false;
    }

    /// <summary>
    /// 获取将要进入的新手引导副本ID
    /// </summary>
    public int GetGuideFubenID()
    {
        //这里是为了删除之前的文件
        string path = Application.persistentDataPath + "//" + "kadingche";
        if (File.Exists(path)) { File.Delete(path); }

        ArrayList strList = GameTool.GetFile("guide");
        if (strList == null) { return 0; }
        int startId = DBSystemMgr.GetSingleton().GetGlobalInt(20);
        return startId + strList.Count;
    }

    /// <summary>
    /// 设置新手引导关卡完成
    /// </summary>
    public void SetFinishGuideFuben(int fubenLevel)
    {
        if (fubenLevel == 1)
        {
            GameTool.CreatFile("guide", "1");
        }
        else if (fubenLevel == 2)
        {
            GameTool.CreatFile("guide", "2");
        }
        else if (fubenLevel == 3)
        {
            GameTool.CreatFile("guide", "3");
        }
    }

    private void OnEnterFuben(ZEvent ev)
    {
        var sceneClass =TableDataMgr.SceneClassMgr.GetItemById(GetGuideFubenID());
        ZMgr.SceneMgr.LoadScene(sceneClass.SceneName);
    }
}